package com.sqoq.downloader3.base_ddg

import android.content.DialogInterface
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.view.*
import android.view.View.OnTouchListener
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.widget.RelativeLayout
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.lifecycleScope
import com.gyf.immersionbar.ImmersionBar
import com.sqoq.downloader3.R
import com.sqoq.downloader3.RepuestTool
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import me.jessyan.autosize.utils.AutoSizeUtils.getWindowWidth

abstract class BaseDialogFragment_ddg<E : ViewDataBinding> : DialogFragment() {
    lateinit var binding: E
    private lateinit var dialogFragmentHelper_ddg: DialogFragmentHelper_ddg
    private lateinit var view: View
    val request: RepuestTool by lazy {
        RepuestTool(lifecycleScope)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        if (dialog != null) {
            try {
                // 解决Dialog内D存泄漏
                dialog?.setOnDismissListener(null)
                dialog?.setOnCancelListener(null)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    override fun show(manager: FragmentManager, tag: String?) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
            if (manager.isDestroyed) {
                return
            }
        }
        try {
            //在每个add事务前增加一个remove事务，防止连续的add
            manager.beginTransaction().remove(this).commitAllowingStateLoss()
            manager.beginTransaction().add(this, tag).commitAllowingStateLoss()
            //            super.show(manager, tag);
        } catch (e: Exception) {
            //同一实例使用不同的tag会异常，这里捕获一下
            e.printStackTrace()
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //全屏
        setStyle(STYLE_NORMAL, R.style.MyDialog_ddg)

        dialogFragmentHelper_ddg = DialogFragmentHelper_ddg()

        dialogFragmentHelper_ddg.width = (getWindowWidth(requireContext()) / 4f * 3.3f).toInt()
        initDialogFragmentProperty(dialogFragmentHelper_ddg)
    }

    protected fun <T> request(
        apiCall: suspend CoroutineScope.() -> T,
        onStart: () -> Unit = {},
        onSuccess: (T) -> Unit = {},
        onError: (T) -> Unit = {},
        onComplete: () -> Unit = {},
        onCancel: () -> Unit = {},
        onHttpError: (Throwable?) -> Unit = {},
        onFinally: () -> Unit = {},
        showLoading: Boolean = true,
        showErrorToast: Boolean = true,
        showHttpErrorToast: Boolean = true
    ): Job {

        return request.request(
            apiCall,
            onStart,
            onSuccess,
            onError,
            onComplete,
            onCancel,
            onHttpError,
            onFinally,
            showLoading,
            showErrorToast,
            showHttpErrorToast
        )
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val contentLayout = RelativeLayout(context)
        val contentLayoutParams = RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT
        )
        contentLayout.layoutParams = contentLayoutParams
        contentLayout.gravity = dialogFragmentHelper_ddg.gravity
        contentLayout.fitsSystemWindows = dialogFragmentHelper_ddg.isFitsSystemWindows
        view = inflater.inflate(layout, container, false)
        contentLayout.addView(view)
        if (dialogFragmentHelper_ddg.isCanceledOnTouchBack) {
            val topPadding = intArrayOf(0)
            val leftPadding = intArrayOf(0)
            val width = intArrayOf(0)
            val height = intArrayOf(0)
            val draw = booleanArrayOf(false)
            contentLayout.viewTreeObserver.addOnGlobalLayoutListener(OnGlobalLayoutListener {
                //设置弹窗在屏幕中的位置
                if (draw[0]) {
                    return@OnGlobalLayoutListener
                }
                width[0] = view.getWidth()
                height[0] = view.getHeight()
                val location = IntArray(2)
                view.getLocationOnScreen(location)
                topPadding[0] = view.getTop()
                leftPadding[0] = view.getLeft()
            })
            contentLayout.setOnTouchListener(OnTouchListener { v: View?, event: MotionEvent ->
                if (event.action == MotionEvent.ACTION_DOWN) {
                    if (event.rawX > leftPadding[0] && event.rawX < leftPadding[0] + width[0]) {
                        if (event.rawY > topPadding[0] && event.rawY < topPadding[0] + height[0]) {
                            return@OnTouchListener false
                        }
                    }
                    dismiss()
                    return@OnTouchListener true
                }
                false
            })
        }
        return contentLayout
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = DataBindingUtil.bind(this.view)!!
        initImmersionBar()
        init()
        if (!dialogFragmentHelper_ddg.isNeedRefresh) {
            initData()
        }
    }

    override fun onStart() {
        super.onStart()
        val dialog = dialog
        //点击外部消失
        dialog!!.setCanceledOnTouchOutside(dialogFragmentHelper_ddg.isCanceledOnTouchOutside)
        val mWindow = dialog.window
        mWindow!!.setWindowAnimations(dialogFragmentHelper_ddg.windowAnimations)
        val windowLayoutParams = mWindow.attributes
        //Dialog必须全屏才能改变状态栏和导航栏的颜色和状态
        windowLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
        windowLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
        windowLayoutParams.dimAmount =
            if (dialogFragmentHelper_ddg.isMaskLayerTransparent) 0f else 0.6f
        mWindow.attributes = windowLayoutParams

        dialog.setOnKeyListener(DialogInterface.OnKeyListener { dialog1: DialogInterface?, keyCode: Int, event: KeyEvent? ->
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (dialogFragmentHelper_ddg.isCanceledOnTouchBack) {
                    dismiss()
                }
            }
            true
        })

        val viewLayoutParams = RelativeLayout.LayoutParams(
            dialogFragmentHelper_ddg.width, dialogFragmentHelper_ddg!!.height
        )
        view.layoutParams = viewLayoutParams
    }

    override fun onResume() {
        super.onResume()
        if (dialogFragmentHelper_ddg.isNeedRefresh) {
            initData()
        }
    }

    /**
     * 初始化沉浸式
     */
    protected open fun initImmersionBar() {

        val immersionBar = ImmersionBar.with(this)
            .statusBarDarkFont(true)
            .flymeOSStatusBarFontColor(android.R.color.black)
            .transparentStatusBar()
            .navigationBarColor(R.color.white)
             .keyboardMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED)
            .keyboardEnable(true)
        //        immersionBar.reset();//一键重置所有参数
        immersionBar.init()
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        initImmersionBar()
    }


    override fun onDestroyView() {
        super.onDestroyView()
        binding.unbind()
        dismiss?.invoke()
        if (activity is BaseActivity_ddg<*>) {
            (activity as BaseActivity_ddg<*>)?.initImmersionBar()
        }
    }

    var dismiss: (() -> Unit)? = null

    @get:LayoutRes
    protected abstract val layout: Int

    /**
     * 设置dialogFragment属性
     *
     * @param dialogFragmentHelper_ddg
     */
    protected abstract fun initDialogFragmentProperty(dialogFragmentHelper_ddg: DialogFragmentHelper_ddg?)
    protected abstract fun init()
    protected abstract fun initData()

}